﻿using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;

using NetFramework.Configuration;
using NetFramework.Collection;

namespace NetFramework.Web.Configuration
{
    /// <summary>
    /// 
    /// </summary>
    [ConfigFile("Configs/Resources/Scripts/*.config")]
	[XmlRoot("scriptConfig")]
    public class ScriptConfig
    {
		private KeyedCollection<ScriptMapping> scriptMappings;
		private SharedScriptGroups sharedScriptGroups;
		private PrivateScriptGroups privateScriptGroups;

		/// <summary>
		/// 
		/// </summary>
		[XmlArray("scriptMappings")]
		[XmlArrayItem("add")]
		public KeyedCollection<ScriptMapping> ScriptMappings
		{
			get { return scriptMappings; }
			set { scriptMappings = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		[XmlElement("sharedScriptGroups")]
		public SharedScriptGroups SharedScriptGroups
		{
			get { return sharedScriptGroups; }
			set { sharedScriptGroups = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		[XmlArray("privateScriptGroups")]
		[XmlArrayItem("scriptGroup")]
		public PrivateScriptGroups PrivateScriptGroups
		{
			get { return privateScriptGroups; }
			set { privateScriptGroups = value; }
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="scriptName"></param>
		/// <returns></returns>
		public ScriptMapping GetScript(string scriptName)
		{
			return ScriptMappings[scriptName];
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="pageName"></param>
		/// <returns></returns>
		public List<ScriptMapping> GetScriptListInPage(string pageName)
		{
			List<ScriptMapping> scriptMappingList = new List<ScriptMapping>();

			PrivateScriptGroup privateScriptGroup = PrivateScriptGroups.GetPrivateScriptGroup(pageName);
			// 处理Shared Script
			SharedScriptGroup sharedScriptGroup = null;
			if (privateScriptGroup != null)
			{
				if (!string.IsNullOrEmpty(privateScriptGroup.SharedScriptGroup))
				{
					sharedScriptGroup = SharedScriptGroups.GetScriptGroup(privateScriptGroup.SharedScriptGroup);
				}
			}

			if (sharedScriptGroup == null)
			{
				sharedScriptGroup = SharedScriptGroups.DefaultScriptGroup;
			}

			if (sharedScriptGroup != null)
			{
				AddScripts(scriptMappingList, sharedScriptGroup.ScriptNames);
			}

			if (privateScriptGroup != null)
			{
				// 处理Private Css
				AddScripts(scriptMappingList, privateScriptGroup.ScriptNames);
			}

            scriptMappingList.Sort(delegate(ScriptMapping x, ScriptMapping y)
            {
                return x.Order.CompareTo(y.Order);
            });

			return scriptMappingList;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="pageName"></param>
		/// <param name="pageZone"></param>
		/// <returns></returns>
		public List<ScriptMapping> GetScriptListInPage(string pageName, PageZone? pageZone)
		{
			List<ScriptMapping> scriptMappingList = new List<ScriptMapping>();

			PrivateScriptGroup privateScriptGroup = PrivateScriptGroups.GetPrivateScriptGroup(pageName);
			// 处理Shared Script
			SharedScriptGroup sharedScriptGroup = null;
			if (privateScriptGroup != null)
			{
				if (!string.IsNullOrEmpty(privateScriptGroup.SharedScriptGroup))
				{
					sharedScriptGroup = SharedScriptGroups.GetScriptGroup(privateScriptGroup.SharedScriptGroup);
				}
			}

			if (sharedScriptGroup == null)
			{
				sharedScriptGroup = SharedScriptGroups.DefaultScriptGroup;
			}

			if (sharedScriptGroup != null)
			{
				AddScripts(scriptMappingList, pageZone, sharedScriptGroup.ScriptNames);
			}

			if (privateScriptGroup != null)
			{
				// 处理Private Css
				AddScripts(scriptMappingList, pageZone, privateScriptGroup.ScriptNames);
			}

            scriptMappingList.Sort(delegate(ScriptMapping x, ScriptMapping y)
            {
                return x.Order.CompareTo(y.Order);
            });

			return scriptMappingList;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="scriptMappingList"></param>
		/// <param name="scriptNames"></param>
		private void AddScripts(List<ScriptMapping> scriptMappingList, params string[] scriptNames)
		{
			if (scriptNames == null)
				return;

			foreach (string scriptName in scriptNames)
			{
				ScriptMapping scriptMapping = scriptMappings[scriptName];
				if (scriptMapping != null && scriptMapping.Enabled)
				{
					scriptMappingList.Add(scriptMapping);
				}
			}
		}

		/// <summary>
		/// 为某页面区域添加脚本。
		/// 如果指定页面区域，只添加可以在该区域显示的脚本。
		/// </summary>
		/// <param name="scriptMappingList"></param>
		/// <param name="pageZone"></param>
		/// <param name="scriptNames"></param>
		private void AddScripts(List<ScriptMapping> scriptMappingList, PageZone? pageZone, params string[] scriptNames)
		{
			if (scriptNames == null)
				return;

			foreach (string scriptName in scriptNames)
			{
				ScriptMapping scriptMapping = scriptMappings[scriptName];
				if (scriptMapping != null && scriptMapping.Enabled)
				{
					if (pageZone.HasValue && pageZone.Value != scriptMapping.PageZone)
						return;

					scriptMappingList.Add(scriptMapping);
				}
			}
		}
    }
}